// pages/river-cropper/river-cropper.js

import {pifyGetImageInfo,pifyCanvasToTempFilePath,pifyChooseImage,touchThrottle,errorDialog} from "./help";

Page({
	data: {
		uploadImg: "",
		uploadImgTempPath: "",
		uploadImgInfo: {
			width: "",
			height: "",
			left: "",
			top: ""
		},
		cropperBox: {
			right: "",
			bottom: "",
			left: "",
			top: ""
		},
		canvasInfo: {
			width: 0,
			height: 0
		},
		availableHeight: "",
		availableWidth: "",
		miniCropperInfo: {
			width: 100,
			height: 100
		}
	},
	onLoad() {
		this.initCropper();
	},
	/**
	 * @description
	 * 初始化裁剪区域
	 */
	initCropper() {
		const { windowWidth, windowHeight } = wx.getSystemInfoSync();
		const deviceRatio = windowWidth / 750;
		const availableHeight = windowHeight - 140 * deviceRatio;
		const availableWidth = windowWidth;
		this.setData({
			availableHeight,
			deviceRatio,
			availableWidth
		});
	},
	/**
	 * @description
	 * 计算图片的比例
	 * 图片宽>高 宽取展示区域宽最大值
	 * 图片高>宽 高最大取展示区域高的最大值
	 */
	countImgRatio() {
		wx.showLoading({
			title: "加载中..."
		});
		let { uploadImg, availableWidth, availableHeight,miniCropperInfo } = this.data;
		let uploadImgWidth = "";
		let uploadImgHeight = "";
		let uploadImgLeft = "";
		let uploadImgTop = "";
		let uploadImgRight = "";
		let uploadImgBottom = "";
		pifyGetImageInfo({
			src: uploadImg
		})
			.then(res => {
				wx.hideLoading();
				const { height, width, path } = res;
				const ImgRadio = width / height;
				if (width >= height) {
					uploadImgWidth = availableWidth;
					uploadImgHeight = availableWidth / ImgRadio;
				} else {
					uploadImgHeight = availableHeight;
					uploadImgWidth = availableHeight * ImgRadio;
					//如果高度太高宽度放不下
					if (uploadImgWidth > availableWidth) {
						uploadImgWidth = availableWidth;
						uploadImgHeight = availableWidth / ImgRadio;
					}
					// 如果图片的高度小于最小高度
				}
				uploadImgLeft = (availableWidth - uploadImgWidth) / 2;
				uploadImgTop = (availableHeight - uploadImgHeight) / 2;
				uploadImgRight =
					availableWidth - (uploadImgLeft + uploadImgWidth);
				uploadImgBottom =
					availableHeight - (uploadImgTop + uploadImgHeight);
				this.setData({
					uploadImgInfo: {
						width: uploadImgWidth,
						height: uploadImgHeight,
						left: uploadImgLeft,
						top: uploadImgTop,
						right: uploadImgRight,
						bottom: uploadImgBottom
					},
					uploadImgTempPath: path
				});
				this.initCropperBox();
			})
			.catch(err => {
				wx.hideLoading();
				errorDialog(err);
			});
	},
	/**
	 * @description
	 * 初始化裁剪框
	 * 选择框的默认值  为图片宽高最小值的一半
	 */
	initCropperBox() {
		let { uploadImgInfo,miniCropperInfo} = this.data;

		let cropperBoxWidth = 0;
		let cropperBoxHeight = 0;
		let cropperBoxLeft = 0;
		let cropperBoxTop = 0;
		let cropperBoxRight = 0;
		let cropperBoxBottom = 0;
		if (uploadImgInfo.width >= uploadImgInfo.height) {
			cropperBoxHeight = uploadImgInfo.height / 2;

			if(cropperBoxHeight<miniCropperInfo.height){
			if(uploadImgInfo.height>miniCropperInfo.height){
				cropperBoxHeight=miniCropperInfo.height;
				cropperBoxWidth=miniCropperInfo.width;

			}else{
				cropperBoxHeight=cropperBoxHeight*2;
				cropperBoxWidth=cropperBoxHeight;
				this.setData({
					miniCropperInfo:{
						width:cropperBoxWidth,
						height:cropperBoxHeight
					}
				});

			}
			}else{
				cropperBoxWidth = cropperBoxHeight;
			}
		} else {
			cropperBoxWidth = uploadImgInfo.width / 2;
			if(cropperBoxWidth<miniCropperInfo.width){

				if(uploadImgInfo.width>miniCropperInfo.width){
					cropperBoxWidth=miniCropperInfo.width;
					cropperBoxHeight=miniCropperInfo.width;
				}else{
					cropperBoxWidth=cropperBoxWidth*2;
					cropperBoxHeight=cropperBoxWidth;
					this.setData({
						miniCropperInfo:{
							width:cropperBoxWidth,
							height:cropperBoxHeight
						}
					});
				}
			}else{
				cropperBoxHeight = cropperBoxWidth;
			}
		}

		cropperBoxLeft = (uploadImgInfo.width - cropperBoxWidth) / 2;
		cropperBoxTop = (uploadImgInfo.height - cropperBoxHeight) / 2;
		cropperBoxRight =
			uploadImgInfo.width - (cropperBoxLeft + cropperBoxWidth);
		cropperBoxBottom =
			uploadImgInfo.height - (cropperBoxTop + cropperBoxHeight);
		this.setData({
			cropperBox: {
				right: cropperBoxRight,
				bottom: cropperBoxBottom,
				left: cropperBoxLeft,
				top: cropperBoxTop
			}
		});
	},
	/**
	 *
	 * @param {Object} e
	 * @description
	 * 拖动图片touchstart事件
	 * cropperBoxStartX
	 * cropperBoxStartY
	 */
	cropperBoxStart(e) {
		let touch1 = e.touches[0];
		this.cropperBoxStartX = touch1.clientX;
		this.cropperBoxStartY = touch1.clientY;
	},
	/**
	 * @description
	 * 拖动裁剪框touchmove
	 */
	cropperBoxMove: touchThrottle(function(e) {
		let { touches } = e;
		let { cropperBox } = this.data;
		let cropperDistanceX = 0;
		let cropperDistanceY = 0;
		let currentCropperLeft = 0;
		let currentCropperTop = 0;
		if (touches.length >= 1) {
			let touch1 = touches[0];
			cropperDistanceX = touch1.clientX - this.cropperBoxStartX;
			cropperDistanceY = touch1.clientY - this.cropperBoxStartY;
			this.cropperBoxStartX = touch1.clientX;
			this.cropperBoxStartY = touch1.clientY;
		}
		currentCropperLeft = cropperBox.left + cropperDistanceX;
		currentCropperTop = cropperBox.top + cropperDistanceY;
		let cropperBoxRight = cropperBox.right - cropperDistanceX;
		let cropperBoxBottom = cropperBox.bottom - cropperDistanceY;

		let formatCropperData = this.isOverBoundary({
			left: currentCropperLeft,
			right: cropperBoxRight,
			top: currentCropperTop,
			bottom: cropperBoxBottom
		});
		if (Object.is(formatCropperData, true)) {
			return;
		}
		this.setData({
			cropperBox: formatCropperData
		});
	}),
	/**
	 *
	 * @param {Object} cropper 裁剪框的位置信息
	 * @description
	 * 判断裁剪框拖动是否超出图片
	 */
	isOverBoundary(cropper = {}) {
		let { uploadImgInfo, miniCropperInfo,cropperBox } = this.data;

		if(0>cropper.left){
			cropper.left=0;
			cropper.right=cropperBox.right+(cropperBox.left-cropper.left);
		}
		if(0>cropper.right){
			cropper.right=0;
			cropper.left=cropperBox.left+(cropperBox.right-cropper.right);
		}
		if(0>cropper.top){
			cropper.top=0;
			cropper.bottom=cropperBox.bottom+(cropperBox.top-cropper.top);
		}
		if(0>cropper.bottom){
			cropper.bottom=0;
			cropper.top=cropperBox.top+(cropperBox.bottom-cropper.bottom);
		}

		let cropperWidth =
			uploadImgInfo.width - (cropper.right + cropper.left);
		let cropperHeight =
			uploadImgInfo.height - (cropper.top + cropper.bottom);
		if (
			cropperWidth < miniCropperInfo.width ||
			cropperHeight < miniCropperInfo.height
		) {
			return true;
		}
		return cropper;
	},
	/**
	 *
	 * @param {*} e
	 * @description
	 * 拖动四角开始
	 */
	cropperTouchstart(e) {
		let touch1 = e.touches[0];
		let { cropperBox } = this.data;
		if (touch1) {
			this.dragStartX = touch1.clientX;
			this.dragStartY = touch1.clientY;
			this.cropperBoxRightStart = cropperBox.right;
			this.cropperBoxBottomStart = cropperBox.bottom;
			this.cropperBoxLeftStart = cropperBox.left;
			this.cropperBoxTopStart = cropperBox.top;
		}
	},
	/**
	 * @description
	 * 拖动四角移动
	 */
	cropperTouchmove: touchThrottle(function(e) {
		//双指滑动 退出
		if(e.touches.length>=2){
			 return;
		}
		let { position } = e.currentTarget.dataset;
		let touch1 = e.touches[0];
		let currentDistanceX = 0;
		let currentDistanceY = 0;
		let cropperRight = this.cropperBoxRightStart;
		let cropperBottom = this.cropperBoxBottomStart;
		let cropperLeft = this.cropperBoxLeftStart;
		let cropperTop = this.cropperBoxTopStart;
		if (touch1) {
			currentDistanceX = touch1.clientX - this.dragStartX;
			currentDistanceY = touch1.clientY - this.dragStartY;
		}
		switch (position) {
			case "leftUpper":
				cropperLeft += currentDistanceX;
				cropperTop += currentDistanceY;
				break;
			case "rightUpper":
				cropperRight -= currentDistanceX;
				cropperTop += currentDistanceY;
				break;
			case "leftLower":
				cropperLeft += currentDistanceX;
				cropperBottom -= currentDistanceY;
				break;
			case "rightLower":
				cropperRight -= currentDistanceX;
				cropperBottom -= currentDistanceY;
				break;
			case "left":
				cropperLeft += currentDistanceX;
				break;
			case "right":
				cropperRight -= currentDistanceX;
				break;
			case "top":
				cropperTop += currentDistanceY;
				break;
			case "bottom":
				cropperBottom -= currentDistanceY;
				break;
			default:
				break;
		}

		let cropperBox = this.isOverBoundary({
			left: cropperLeft,
			right: cropperRight,
			top: cropperTop,
			bottom: cropperBottom
		});
		if (Object.is(cropperBox, true)) {
			return;
		}
		this.setData({
			cropperBox: cropperBox
		});
	}),
	/**
	 *
	 * @param {*} e
	 * 拖动裁剪框的边框
	 */
	cropperBorderTouchstart(e) {
		this.cropperTouchstart.call(this, e);
	},
	/**
	 *
	 * @param {*} e
	 * 拖动裁剪框的边框移动
	 */
	cropperBorderTouchmove(e) {
		this.cropperTouchmove.call(this, e);
	},
	/**
	 * @description
	 * 选择图片
	 */
	seletImage() {
		pifyChooseImage({
			count: 1
		})
			.then(res => {
				let tempPath = res.tempFilePaths[0];
				this.setData({
					uploadImg: tempPath
				});
				this.countImgRatio();
			})
			.catch(err => {
				errorDialog(err);
			});
	},
	/**
	 * @description
	 * 利用canvas绘制图片的裁剪位置 导出图片的临时路径
	 */
	cropperCanvas() {
		wx.showLoading({
			title: "裁剪中..."
		});
		let { cropperBox, uploadImgTempPath, uploadImgInfo } = this.data;
		let canvasWidth =
			uploadImgInfo.width - (cropperBox.left + cropperBox.right);
		let canvasHeight =
			uploadImgInfo.height - (cropperBox.top + cropperBox.bottom);
		this.setData({
			"canvasInfo.width": canvasWidth,
			"canvasInfo.height": canvasHeight
		});
		let cropperCanvas = wx.createCanvasContext("cropperCanvas");
		cropperCanvas.drawImage(
			uploadImgTempPath,
			0,
			0,
			null,
			null,
			-cropperBox.left,
			-cropperBox.top,
			uploadImgInfo.width,
			uploadImgInfo.height
		);
		cropperCanvas.draw(false, () => {
			setTimeout(() => {
				pifyCanvasToTempFilePath({
					canvasId: "cropperCanvas"
				})
					.then(res => {
						wx.hideLoading();
						let { tempFilePath } = res;
						wx.previewImage({
							urls: [tempFilePath]
						});
					})
					.catch(err => {
						wx.hideLoading();
						errorDialog(err);
					});
			}, 300);
		});
	}
});
